home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume8 / unzip_gs < prev    next >
Encoding:
Text File  |  1989-09-23  |  55.7 KB  |  2,034 lines

  1. Newsgroups: comp.sources.misc
  2. organization: not yet
  3. keywords: ZIP archive pkzip
  4. summary: unarchive for ZIP archives under Unix
  5. subject: v08i043: UnZip for Unix
  6. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  7. Reply-To: george@gatech.edu@rebel.UUCP (George M. Sipe)
  8.  
  9. Posting-number: Volume 8, Issue 43
  10. Submitted-by: george@gatech.edu@rebel.UUCP (George M. Sipe)
  11. Archive-name: unzip_gs
  12.  
  13. #! /bin/sh
  14. # This is a shell archive, meaning:
  15. # 1. Remove everything above the #! /bin/sh line.
  16. # 2. Save the resulting text in a file.
  17. # 3. Execute the file with /bin/sh (not csh) to create:
  18. #    README
  19. #    crc32.c
  20. #    crc32.h
  21. #    unzip.c
  22. #    unzip.doc
  23. # This archive created: Sun Sep 17 15:30:42 1989
  24. export PATH; PATH=/bin:/usr/bin:$PATH
  25. if test -f 'README'
  26. then
  27.     echo shar: "will not over-write existing file 'README'"
  28. else
  29. sed 's/^X//' << \SHAR_EOF > 'README'
  30. XEnclosed is version 2.0 of UnZip by Samuel H. Smith.  This software
  31. Xcan unarchive any .ZIP file including those created by the recently
  32. Xreleased pkzip version 1.01.  Personally, I prefer zoo for many
  33. Xreasons, but there will be zip archives out there and this can help.
  34. X
  35. XUnfortunately, the software as released is dependent on the TurboC
  36. Xruntime library, the 80x86 byte ordering, and compiler optimization
  37. Xassumptions.  Not very good at all for easy porting to Unix, or for that
  38. Xmatter, any other C compiler/machine combination.  I have made some
  39. Xsignificant improvements to create UnZip 2.0.1 in order to increase
  40. Xportability, to run under Unix, and to compile on PC's under MicroSoft
  41. XC.  This software has NOT been extensively tested, but appears to
  42. Xwork well so far.
  43. X
  44. XThis version will be sent to the author just as soon as I can finally
  45. Xget throught to his BBS.  I had sent him the same improvements for his
  46. Xlast version (1.5) and explained the benefits of not having zillions of
  47. Xmachine specific versions, but to no avail (there are Amiga and other
  48. Xhacks out there - mine should be generally more portable).  Sam's
  49. Xlicence permits this modified distribtion when the source is included,
  50. Xas it is here.
  51. X
  52. XMy changes among other things, perform such tasks as AUTOMATICALLY
  53. Xadjusting operation for any byte-ordering (if HIGH_LOW is defined)
  54. Xand handling C compilers which do not pack structures on 2 byte
  55. Xboundaries (i.e. move 'longint's to the next 4 byte boundary - this
  56. Xis a common, and frequently unstoppable, optimization).
  57. X
  58. X
  59. XGeorge M. Sipe,               Phone: (404) 447-4731
  60. X537 Lakeshore Drive, Berkeley Lake, GA  30136-3035
  61. XUUCP: ...!{decvax,linus,rutgers}!gatech!rebel!george
  62. SHAR_EOF
  63. fi
  64. if test -f 'crc32.c'
  65. then
  66.     echo shar: "will not over-write existing file 'crc32.c'"
  67. else
  68. sed 's/^X//' << \SHAR_EOF > 'crc32.c'
  69. X/*  --------------------------------------------------------------------  */
  70. X/*  COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or       */
  71. X/*  code or tables extracted from it, as desired without restriction.     */
  72. X/*                                                                        */
  73. X/*  First, the polynomial itself and its table of feedback terms.  The    */
  74. X/*  polynomial is                                                         */
  75. X/*  X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0   */
  76. X/*                                                                        */
  77. X/*  Note that we take it "backwards" and put the highest-order term in    */
  78. X/*  the lowest-order bit.  The X^32 term is "implied"; the LSB is the     */
  79. X/*  X^31 term, etc.  The X^0 term (usually shown as "+1") results in      */
  80. X/*  the MSB being 1.                                                      */
  81. X/*                                                                        */
  82. X/*  Note that the usual hardware shift register implementation, which     */
  83. X/*  is what we're using (we're merely optimizing it by doing eight-bit    */
  84. X/*  chunks at a time) shifts bits into the lowest-order term.  In our     */
  85. X/*  implementation, that means shifting towards the right.  Why do we     */
  86. X/*  do it this way?  Because the calculated CRC must be transmitted in    */
  87. X/*  order from highest-order term to lowest-order term.  UARTs transmit   */
  88. X/*  characters in order from LSB to MSB.  By storing the CRC this way,    */
  89. X/*  we hand it to the UART in the order low-byte to high-byte; the UART   */
  90. X/*  sends each low-bit to hight-bit; and the result is transmission bit   */
  91. X/*  by bit from highest- to lowest-order term without requiring any bit   */
  92. X/*  shuffling on our part.  Reception works similarly.                    */
  93. X/*                                                                        */
  94. X/*  The feedback terms table consists of 256, 32-bit entries.  Notes:     */
  95. X/*                                                                        */
  96. X/*      The table can be generated at runtime if desired; code to do so   */
  97. X/*      is shown later.  It might not be obvious, but the feedback        */
  98. X/*      terms simply represent the results of eight shift/xor opera-      */
  99. X/*      tions for all combinations of data and CRC register values.       */
  100. X/*                                                                        */
  101. X/*      The values must be right-shifted by eight bits by the "updcrc"    */
  102. X/*      logic; the shift must be unsigned (bring in zeroes).  On some     */
  103. X/*      hardware you could probably optimize the shift in assembler by    */
  104. X/*      using byte-swap instructions.                                     */
  105. X/*      polynomial $edb88320                                              */
  106. X/*                                                                        */
  107. X/*  --------------------------------------------------------------------  */
  108. X
  109. Xlong crc_32_tab[] = {
  110. X      0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  111. X      0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  112. X      0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  113. X      0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  114. X      0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  115. X      0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  116. X      0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  117. X      0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  118. X      0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  119. X      0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  120. X      0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  121. X      0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  122. X      0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  123. X      0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  124. X      0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  125. X      0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  126. X      0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  127. X      0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  128. X      0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  129. X      0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  130. X      0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  131. X      0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  132. X      0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  133. X      0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  134. X      0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  135. X      0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  136. X      0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  137. X      0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  138. X      0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  139. X      0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  140. X      0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  141. X      0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  142. X      0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  143. X      0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  144. X      0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  145. X      0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  146. X      0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  147. X      0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  148. X      0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  149. X      0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  150. X      0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  151. X      0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  152. X      0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  153. X      0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  154. X      0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  155. X      0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  156. X      0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  157. X      0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  158. X      0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  159. X      0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  160. X      0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  161. X      0x2d02ef8dL
  162. X   };
  163. X
  164. X#ifndef    TURBOC
  165. Xtypedef    unsigned char    byte;
  166. X#endif    /* !TURBOC */
  167. X
  168. X#define UPDCRC32(res,oct) \
  169. X    res=crc_32_tab[(byte)res ^ (byte)oct] ^ ((res >> 8) & 0x00FFFFFFL)
  170. X
  171. X/*
  172. X * Inline assembly version of 32 bit CRC calculation
  173. X * Copyright 1989 Samuel H. Smith
  174. X *
  175. X * You may use this program, or code extracted from it,
  176. X * as desired without restriction.
  177. X *
  178. X */
  179. X
  180. Xextern long crc32val;
  181. X
  182. X/* update running CRC calculation with contents of a buffer */
  183. X
  184. X#ifndef    OLDC
  185. Xvoid UpdateCRC(unsigned char *s, register int len)
  186. X#else
  187. Xvoid UpdateCRC(s, len)
  188. Xunsigned char *s;
  189. Xregister int len;
  190. X#endif    /* OLDC */
  191. X{
  192. X#ifndef    TURBOC
  193. X        while (len--) {
  194. X                UPDCRC32(crc32val, *s++);
  195. X        }
  196. X#else
  197. X        asm     push cx
  198. X        asm     push si
  199. X
  200. X        asm     mov cx,len
  201. X
  202. X        asm     les si,s
  203. X
  204. X        asm     mov dx,crc32val+2
  205. X        asm     mov ax,crc32val
  206. X
  207. XcrcNext:
  208. X        asm     mov bh,al       /* save crc32val[0] */
  209. X
  210. X        asm     mov al,ah       /* (crc32 >> 8) & 0x00ffffff */
  211. X        asm     mov ah,dl
  212. X        asm     mov dl,dh
  213. X        asm     xor dh,dh
  214. X
  215. X        asm     mov bl,es:[si]
  216. X        asm     inc si
  217. X
  218. X        asm     xor bl,bh       /* crcval[0] */
  219. X
  220. X        asm     xor bh,bh
  221. X        asm     shl bx,1
  222. X        asm     shl bx,1
  223. X        asm     xor ax,crc_32_tab[bx]
  224. X        asm     xor dx,crc_32_tab[bx+2]
  225. X
  226. X        asm     loop crcNext
  227. X
  228. X        asm     mov crc32val+2,dx
  229. X        asm     mov crc32val,ax
  230. X        asm     pop si
  231. X        asm     pop cx
  232. X#endif    /* TURBOC */
  233. X}
  234. SHAR_EOF
  235. fi
  236. if test -f 'crc32.h'
  237. then
  238.     echo shar: "will not over-write existing file 'crc32.h'"
  239. else
  240. sed 's/^X//' << \SHAR_EOF > 'crc32.h'
  241. Xlong crc32val;
  242. X
  243. X/* update running CRC calculation with contents of a buffer */
  244. X
  245. X#ifndef    OLDC
  246. Xvoid UpdateCRC(unsigned char *s, register int len);
  247. X#else
  248. Xvoid UpdateCRC();
  249. X#endif    /* OLDC */
  250. SHAR_EOF
  251. fi
  252. if test -f 'unzip.c'
  253. then
  254.     echo shar: "will not over-write existing file 'unzip.c'"
  255. else
  256. sed 's/^X//' << \SHAR_EOF > 'unzip.c'
  257. X
  258. X/*
  259. X * Copyright 1989 Samuel H. Smith;  All rights reserved
  260. X *
  261. X * Do not distribute modified versions without my permission.
  262. X * Do not remove or alter this notice or any other copyright notice.
  263. X * If you use this in your own program you must distribute source code.
  264. X * Do not use any of this in a commercial product.
  265. X *
  266. X */
  267. X
  268. X/*
  269. X * UnZip - A simple zipfile extract utility
  270. X *
  271. X * To compile:
  272. X *      tcc -B -O -Z -G -mc unzip.c    ;turbo C 2.0, compact model
  273. X *    cl /O /AC /G0 /W3 -c unzip.    ;msc 5.1, compact model
  274. X *    cc -O -DOLDC -Dunix {-DHIGH_LOW} {-DSHORTC} -c unzip.c    ;unix pcc
  275. X *
  276. X * Port to Unix and MSC (i.e. "portable version") by George M. Sipe
  277. X * (rebel!george).
  278. X *
  279. X */
  280. X
  281. X#define VERSION  \
  282. X    "UnZip:  Zipfile Extract v2.0.1 of 09-16-89;  (C) 1989 Samuel H. Smith"
  283. X
  284. X#ifdef    SHORTC
  285. X#define    compressed_size        cmpr_sz
  286. X#define    extract_zipfile        ext_zip
  287. X#define    filename        fn
  288. X#define    follower        flwr
  289. X#define    hsize_array_byte    hsz_a_byte
  290. X#define    last_mod_file_date    mod_fdate
  291. X#define    lit_tree_present    lt_present
  292. X#define    maxcodemax        mx_cd_mx
  293. X#define    number_disk_with_start_central_directory ndwsc
  294. X#define    process_central_file_header pcfhdr
  295. X#define    process_end_central_dir    pecdir
  296. X#define    process_headers        proc_hdrs
  297. X#define    total_entries_central_dir tecdir
  298. X#define    version_made_by        v_made_by
  299. X#define    LoadTrees        LdTrees
  300. X#endif    /* SHORTC */
  301. X
  302. Xtypedef unsigned char byte;    /* code assumes UNSIGNED bytes */
  303. Xtypedef long longint;        /* sizeof must be 4 bytes */
  304. Xtypedef unsigned short word;    /* sizeof must be 2 bytes */
  305. Xtypedef char boolean;
  306. X
  307. X#define STRSIZ 256
  308. X
  309. X#include <stdio.h>
  310. X /* this is your standard header for all C compiles */
  311. X
  312. X#ifndef    OLDC
  313. X#include <stdlib.h>
  314. X /* this include defines various standard library prototypes */
  315. X#define    VOIDARG    void        /* function definitions support (void) */
  316. X#else
  317. X#include <ctype.h>
  318. X#define    VOIDARG            /* function definitions support () only */
  319. X#endif    /* OLDC */
  320. X
  321. X
  322. X/*
  323. X * SEE HOST OPERATING SYSTEM SPECIFICS SECTION STARTING NEAR LINE 180
  324. X *
  325. X */
  326. X
  327. X
  328. X/* ----------------------------------------------------------- */
  329. X/*
  330. X * Zipfile layout declarations
  331. X *
  332. X */
  333. X
  334. Xtypedef longint signature_type;
  335. X
  336. X
  337. X#define LOCAL_FILE_HEADER_SIGNATURE  0x04034b50L
  338. X
  339. X
  340. Xtypedef struct local_file_header {
  341. X    word version_needed_to_extract;
  342. X        word general_purpose_bit_flag;
  343. X    word compression_method;
  344. X    word last_mod_file_time;
  345. X    word last_mod_file_date;
  346. X    longint crc32;
  347. X    longint compressed_size;
  348. X        longint uncompressed_size;
  349. X    word filename_length;
  350. X    word extra_field_length;
  351. X} local_file_header;
  352. X
  353. X
  354. X#define CENTRAL_FILE_HEADER_SIGNATURE  0x02014b50L
  355. X
  356. X
  357. Xtypedef struct central_directory_file_header {
  358. X    word version_made_by;
  359. X    word version_needed_to_extract;
  360. X    word general_purpose_bit_flag;
  361. X    word compression_method;
  362. X    word last_mod_file_time;
  363. X    word last_mod_file_date;
  364. X    longint crc32;
  365. X    longint compressed_size;
  366. X    longint uncompressed_size;
  367. X    word filename_length;
  368. X    word extra_field_length;
  369. X    word file_comment_length;
  370. X    word disk_number_start;
  371. X    word internal_file_attributes;
  372. X    longint external_file_attributes;
  373. X    longint relative_offset_local_header;
  374. X} central_directory_file_header;
  375. X
  376. X
  377. X#define END_CENTRAL_DIR_SIGNATURE  0x06054b50L
  378. X
  379. X
  380. Xtypedef struct end_central_dir_record {
  381. X    word number_this_disk;
  382. X#ifndef    TURBOC
  383. X    word num_disk_with_start_cent_dir;
  384. X    word tot_ents_cent_dir_on_this_disk;
  385. X#else
  386. X    word number_disk_with_start_central_directory;
  387. X    word total_entries_central_dir_on_this_disk;
  388. X#endif    /* TURBOC */
  389. X    word total_entries_central_dir;
  390. X    longint size_central_directory;
  391. X    longint offset_start_central_directory;
  392. X    word zipfile_comment_length;
  393. X} end_central_dir_record;
  394. X
  395. X
  396. X
  397. X/* ----------------------------------------------------------- */
  398. X/*
  399. X * input file variables
  400. X *
  401. X */
  402. X
  403. X#define INBUFSIZ 0x2000
  404. Xbyte *inbuf;            /* input file buffer - any size is legal */
  405. Xbyte *inptr;
  406. X
  407. Xint incnt;
  408. Xunsigned bitbuf;
  409. Xint bits_left;
  410. Xboolean zipeof;
  411. X
  412. Xint zipfd;
  413. Xchar zipfn[STRSIZ];
  414. Xlocal_file_header lrec;
  415. X
  416. X#ifdef    HIGH_LOW
  417. Xint w0, w1;            /* word translation indices */
  418. Xint li0, li1, li2, li3;        /* long int translation indices */
  419. X#endif    /* HIGH_LOW */
  420. X
  421. X
  422. X/* ----------------------------------------------------------- */
  423. X/*
  424. X * output stream variables
  425. X *
  426. X */
  427. X
  428. X#define OUTBUFSIZ 0x2000        /* must be 0x2000 or larger for unImplode */
  429. Xbyte *outbuf;                   /* buffer for rle look-back */
  430. Xbyte *outptr;
  431. X
  432. Xlongint outpos;            /* absolute position in outfile */
  433. Xint outcnt;            /* current position in outbuf */
  434. X
  435. Xint outfd;
  436. Xchar filename[STRSIZ];
  437. Xchar extra[STRSIZ];
  438. X
  439. X#define DLE 144
  440. X
  441. X
  442. X/* ----------------------------------------------------------- */
  443. X/*
  444. X * shrink/reduce working storage
  445. X *
  446. X */
  447. X
  448. Xint factor;
  449. Xbyte followers[256][64];
  450. Xbyte Slen[256];
  451. X
  452. X#define max_bits 13
  453. X#define init_bits 9
  454. X#define hsize 8192
  455. X#define first_ent 257
  456. X#define clear 256
  457. X
  458. Xtypedef int hsize_array_integer[hsize+1];
  459. Xtypedef byte hsize_array_byte[hsize+1];
  460. X
  461. Xhsize_array_integer prefix_of;
  462. Xhsize_array_byte suffix_of;
  463. Xhsize_array_byte stack;
  464. X
  465. Xint codesize;
  466. Xint maxcode;
  467. Xint free_ent;
  468. Xint maxcodemax;
  469. Xint offset;
  470. Xint sizex;
  471. X
  472. X
  473. X
  474. X/* ============================================================= */
  475. X/*
  476. X * Host operating system details
  477. X *
  478. X */
  479. X
  480. X#include <string.h>
  481. X /* this include defines strcpy, strcmp, etc. */
  482. X
  483. X#ifndef    TURBOC
  484. X#include <sys/types.h>
  485. X /*
  486. X  * this include file defines
  487. X  *        dev_t (* device type *)
  488. X  * as used in the sys/utime.h and sys/stat.h header files below
  489. X  */
  490. X
  491. X#ifndef    OLDC
  492. X#include <sys/utime.h>
  493. X /*
  494. X  * this include file defines
  495. X  *        struct utimbuf (* utime buffer structure *)
  496. X  *        utime()        (* utime function *)
  497. X  * as used in the set_file_time() function defined below
  498. X  */
  499. X#endif    /* !OLDC */
  500. X#endif    /* !TURBOC */
  501. X
  502. X#ifndef    TURBOC
  503. X#include <time.h>
  504. Xstruct ftime {
  505. X    unsigned ft_tsec: 5;    /* two seconds */
  506. X    unsigned ft_min: 6;    /* minutes */
  507. X    unsigned ft_hour: 5;    /* hours */
  508. X    unsigned ft_day: 5;    /* days */
  509. X    unsigned ft_month: 4;    /* months */
  510. X    unsigned ft_year: 7;    /* years  - 1980 */
  511. X};
  512. X#endif    /* TURBOC */
  513. X#ifndef    OLDC
  514. X#include <io.h>
  515. X#else
  516. X#include <sys/file.h>
  517. X#ifdef    L_SET
  518. X#define    SEEK_SET    L_SET
  519. X#else
  520. X#define    SEEK_SET    0
  521. X#endif    /* L_SET */
  522. X#endif    /* OLDC */
  523. X /*
  524. X  * this include file defines
  525. X  *             struct ftime ...        (* file time/date stamp info *)
  526. X  *             int setftime (int handle, struct ftime *ftimep);
  527. X  *             #define SEEK_CUR  1     (* lseek() modes *)
  528. X  *             #define SEEK_END  2
  529. X  *             #define SEEK_SET  0
  530. X  */
  531. X
  532. X#include <fcntl.h>
  533. X#ifndef    O_BINARY
  534. X#define    O_BINARY    0
  535. X#endif    /* O_BINARY */
  536. X /*
  537. X  * this include file defines
  538. X  *             #define O_BINARY 0x8000  (* no cr-lf translation *)
  539. X  * as used in the open() standard function
  540. X  */
  541. X
  542. X#include <sys/stat.h>
  543. X /*
  544. X  * this include file defines
  545. X  *             #define S_IREAD 0x0100  (* owner may read *)
  546. X  *             #define S_IWRITE 0x0080 (* owner may write *)
  547. X  * as used in the creat() standard function
  548. X  */
  549. X
  550. X/* #undef HIGH_LOW - define externally */
  551. X /*
  552. X  * change 'undef' to 'define' if your machine stores high order bytes in
  553. X  * lower addresses.
  554. X  */
  555. X
  556. Xvoid set_file_time(VOIDARG)
  557. X /*
  558. X  * set the output file date/time stamp according to information from the
  559. X  * zipfile directory record for this file 
  560. X  */
  561. X{
  562. X    union {
  563. X                struct ftime ft;        /* system file time record */
  564. X        struct {
  565. X                        word ztime;     /* date and time words */
  566. X                        word zdate;     /* .. same format as in .ZIP file */
  567. X        } zt;
  568. X    } td;
  569. X
  570. X    /*
  571. X     * set output file date and time - this is optional and can be
  572. X     * deleted if your compiler does not easily support setftime() 
  573. X     */
  574. X#ifdef    TURBOC
  575. X    td.zt.ztime = lrec.last_mod_file_time;
  576. X    td.zt.zdate = lrec.last_mod_file_date;
  577. X
  578. X    setftime(outfd, &td.ft);
  579. X#else
  580. X
  581. X#define leap(y)     (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)
  582. X#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)
  583. X
  584. X    static char month_lengths[] =
  585. X        { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  586. X    int day_of_year, year;
  587. X#ifndef    OLDC
  588. X    struct utimbuf times;
  589. X#else
  590. X    struct utimbuf {
  591. X        time_t actime;        /* file accessed time */
  592. X        time_t modtime;        /* file updated time */
  593. X    } times;
  594. X#endif    /* OLDC */
  595. X
  596. X    /*
  597. X     * this is the standard Unix implementation (also fully
  598. X     * compatible with MSC)
  599. X     */
  600. X
  601. X    close(outfd);
  602. X    td.zt.ztime = lrec.last_mod_file_time;
  603. X    td.zt.zdate = lrec.last_mod_file_date;
  604. X    year = td.ft.ft_year + 1980;
  605. X    if (td.ft.ft_month < 1 || td.ft.ft_month > 12 || td.ft.ft_day < 1
  606. X        || td.ft.ft_day > month_lengths[td.ft.ft_month-1]
  607. X        && !(td.ft.ft_month == 2 && td.ft.ft_day == 29 && leap (year))
  608. X        || td.ft.ft_hour > 23 || td.ft.ft_min > 59 ||
  609. X        td.ft.ft_tsec*2 > 59)
  610. X        return;
  611. X    day_of_year = td.ft.ft_day - 1;
  612. X    if (td.ft.ft_month > 2 && leap(year)) ++day_of_year;
  613. X    while (--td.ft.ft_month > 0)
  614. X        day_of_year += month_lengths[td.ft.ft_month - 1];
  615. X    times.modtime = (86400 * (long)(day_of_year + 365 * (year - 1970) 
  616. X        + nleap (year)) + 3600 * (td.ft.ft_hour-1) + 60 * td.ft.ft_min
  617. X        + td.ft.ft_tsec*2);
  618. X#ifdef    HAVE_TZ
  619. X    tzset();
  620. X    times.modtime += timezone;
  621. X#endif    /* HAVE_TZ */
  622. X    times.actime = times.modtime;
  623. X    utime(filename, ×);
  624. X#endif    /* !TURBOC */
  625. X}
  626. X
  627. X
  628. Xint create_output_file(VOIDARG)
  629. X /* return non-0 if creat failed */
  630. X{
  631. X    /* create the output file with READ and WRITE permissions */
  632. X    outfd = creat(filename, S_IWRITE | S_IREAD | S_IREAD >> 3
  633. X            | S_IREAD >> 6);
  634. X    if (outfd < 1) {
  635. X        printf("Can't create output: %s\n", filename);
  636. X        return 1;
  637. X    }
  638. X
  639. X    /*
  640. X     * close the newly created file and reopen it in BINARY mode to
  641. X     * disable all CR/LF translations 
  642. X     */
  643. X    close(outfd);
  644. X    outfd = open(filename, O_RDWR | O_BINARY);
  645. X
  646. X    /* write a single byte at EOF to pre-allocate the file */
  647. X#ifdef    tx
  648. X    fsetsize(outfd, lrec.uncompressed_size);
  649. X#endif    /* tx */
  650. X        lseek(outfd, lrec.uncompressed_size - 1L, SEEK_SET);
  651. X    write(outfd, "?", 1);
  652. X    lseek(outfd, 0L, SEEK_SET);
  653. X    return 0;
  654. X}
  655. X
  656. X
  657. Xint open_input_file(VOIDARG)
  658. X /* return non-0 if creat failed */
  659. X{
  660. X    /*
  661. X     * open the zipfile for reading and in BINARY mode to prevent cr/lf
  662. X     * translation, which would corrupt the bitstreams 
  663. X     */
  664. X
  665. X    zipfd = open(zipfn, O_RDONLY | O_BINARY);
  666. X    if (zipfd < 1) {
  667. X        printf("Can't open input file: %s\n", zipfn);
  668. X        return (1);
  669. X    }
  670. X    return 0;
  671. X}
  672. X
  673. X
  674. X#ifdef HIGH_LOW
  675. X
  676. X#ifndef    OLDC
  677. Xvoid swap_bytes(word *wordp)
  678. X#else
  679. Xvoid swap_bytes(wordp)
  680. Xword *wordp;
  681. X#endif    /* OLDC */
  682. X /* convert intel style 'short int' variable to host format */
  683. X{
  684. X    char *charp = (char *) wordp;
  685. X    char temp[2];
  686. X
  687. X    temp[0] = charp[w0];
  688. X    temp[1] = charp[w1];
  689. X    charp[0] = temp[0];
  690. X    charp[1] = temp[1];
  691. X}
  692. X
  693. X#ifndef    OLDC
  694. Xvoid swap_lbytes(longint *longp)
  695. X#else
  696. Xvoid swap_lbytes(longp)
  697. Xlongint *longp;
  698. X#endif    /* OLDC */
  699. X /* convert intel style 'long' variable to host format */
  700. X{
  701. X    char *charp = (char *) longp;
  702. X    char temp[4];
  703. X
  704. X    temp[0] = charp[li0];
  705. X    temp[1] = charp[li1];
  706. X    temp[2] = charp[li2];
  707. X    temp[3] = charp[li3];
  708. X    charp[0] = temp[0];
  709. X    charp[1] = temp[1];
  710. X    charp[2] = temp[2];
  711. X    charp[3] = temp[3];
  712. X}
  713. X
  714. X#endif    /* HIGH_LOW */
  715. X
  716. X
  717. X
  718. X/* ============================================================= */
  719. X
  720. Xint FillBuffer(VOIDARG)
  721. X /* fill input buffer if possible */
  722. X{
  723. X    int readsize;
  724. X
  725. X        if (lrec.compressed_size <= 0)
  726. X        return incnt = 0;
  727. X
  728. X        if (lrec.compressed_size > INBUFSIZ)
  729. X        readsize = INBUFSIZ;
  730. X    else
  731. X                readsize = (int) lrec.compressed_size;
  732. X    incnt = read(zipfd, inbuf, readsize);
  733. X
  734. X        lrec.compressed_size -= incnt;
  735. X    inptr = inbuf;
  736. X    return incnt--;
  737. X}
  738. X
  739. X#ifndef    OLDC
  740. Xint ReadByte(unsigned *x)
  741. X#else
  742. Xint ReadByte(x)
  743. Xunsigned *x;
  744. X#endif    /* OLDC */
  745. X /* read a byte; return 8 if byte available, 0 if not */
  746. X{
  747. X    if (incnt-- == 0)
  748. X        if (FillBuffer() == 0)
  749. X            return 0;
  750. X
  751. X    *x = *inptr++;
  752. X    return 8;
  753. X}
  754. X
  755. X
  756. X/* ------------------------------------------------------------- */
  757. Xstatic unsigned mask_bits[] =
  758. X        {0,     0x0001, 0x0003, 0x0007, 0x000f,
  759. X                0x001f, 0x003f, 0x007f, 0x00ff,
  760. X                0x01ff, 0x03ff, 0x07ff, 0x0fff,
  761. X                0x1fff, 0x3fff, 0x7fff, 0xffff
  762. X        };
  763. X
  764. X
  765. X#ifndef    OLDC
  766. Xint FillBitBuffer(register int bits)
  767. X#else
  768. Xint FillBitBuffer(bits)
  769. Xregister int bits;
  770. X#endif    /* OLDC */
  771. X /* read a byte; return 8 if byte available, 0 if not */
  772. X{
  773. X    /* get the bits that are left and read the next word */
  774. X    unsigned temp;
  775. X        register int result = bitbuf;
  776. X    int sbits = bits_left;
  777. X    bits -= bits_left;
  778. X
  779. X    /* read next word of input */
  780. X    bits_left = ReadByte(&bitbuf);
  781. X    bits_left += ReadByte(&temp);
  782. X    bitbuf |= (temp << 8);
  783. X    if (bits_left == 0)
  784. X        zipeof = 1;
  785. X
  786. X    /* get the remaining bits */
  787. X        result = result | (int) ((bitbuf & mask_bits[bits]) << sbits);
  788. X        bitbuf >>= bits;
  789. X        bits_left -= bits;
  790. X        return result;
  791. X}
  792. X
  793. X#define READBIT(nbits,zdest,ztype) \
  794. X    { if (nbits <= bits_left) \
  795. X        { zdest = ztype(bitbuf & mask_bits[nbits]); \
  796. X        bitbuf >>= nbits; bits_left -= nbits; } \
  797. X    else zdest = ztype(FillBitBuffer(nbits));}
  798. X
  799. X/*
  800. X * macro READBIT(nbits,zdest,ztype)
  801. X *  {
  802. X *      if (nbits <= bits_left) {
  803. X *          zdest = ztype(bitbuf & mask_bits[nbits]);
  804. X *          bitbuf >>= nbits;
  805. X *          bits_left -= nbits;
  806. X *      } else
  807. X *          zdest = ztype(FillBitBuffer(nbits));
  808. X *  }
  809. X *
  810. X */
  811. X
  812. X
  813. X/* ------------------------------------------------------------- */
  814. X
  815. X#include "crc32.h"
  816. X
  817. X
  818. X/* ------------------------------------------------------------- */
  819. X
  820. Xvoid FlushOutput(VOIDARG)
  821. X /* flush contents of output buffer */
  822. X{
  823. X    UpdateCRC(outbuf, outcnt);
  824. X    write(outfd, outbuf, outcnt);
  825. X    outpos += outcnt;
  826. X    outcnt = 0;
  827. X    outptr = outbuf;
  828. X}
  829. X
  830. X#define OUTB(intc) { *outptr++=intc; if (++outcnt==OUTBUFSIZ) FlushOutput(); }
  831. X
  832. X/*
  833. X *  macro OUTB(intc)
  834. X *  {
  835. X *      *outptr++=intc;
  836. X *      if (++outcnt==OUTBUFSIZ)
  837. X *          FlushOutput();
  838. X *  }
  839. X *
  840. X */
  841. X
  842. X
  843. X/* ----------------------------------------------------------- */
  844. X
  845. Xvoid LoadFollowers(VOIDARG)
  846. X{
  847. X        register int x;
  848. X        register int i;
  849. X
  850. X    for (x = 255; x >= 0; x--) {
  851. X                READBIT(6,Slen[x],(byte));
  852. X        for (i = 0; i < Slen[x]; i++) {
  853. X                        READBIT(8,followers[x][i],(byte));
  854. X        }
  855. X    }
  856. X}
  857. X
  858. X
  859. X/* ----------------------------------------------------------- */
  860. X/*
  861. X * The Reducing algorithm is actually a combination of two
  862. X * distinct algorithms.  The first algorithm compresses repeated
  863. X * byte sequences, and the second algorithm takes the compressed
  864. X * stream from the first algorithm and applies a probabilistic
  865. X * compression method.
  866. X */
  867. X
  868. Xint L_table[] = {0, 0x7f, 0x3f, 0x1f, 0x0f};
  869. X
  870. Xint D_shift[] = {0, 0x07, 0x06, 0x05, 0x04};
  871. Xint D_mask[]  = {0, 0x01, 0x03, 0x07, 0x0f};
  872. X
  873. Xint B_table[] = {8, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5,
  874. X         5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6,
  875. X         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  876. X         6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
  877. X         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  878. X         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  879. X         7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  880. X         7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  881. X         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  882. X         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  883. X         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  884. X         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  885. X         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  886. X         8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
  887. X         8, 8, 8, 8};
  888. X
  889. X/* ----------------------------------------------------------- */
  890. X
  891. Xvoid unReduce(VOIDARG)
  892. X /* expand probablisticly reduced data */
  893. X{
  894. X        register int lchar;
  895. X        int nchar;
  896. X        int ExState;
  897. X        int V;
  898. X        int Len;
  899. X
  900. X        factor = lrec.compression_method - 1;
  901. X    ExState = 0;
  902. X    lchar = 0;
  903. X    LoadFollowers();
  904. X
  905. X        while (((outpos+outcnt) < lrec.uncompressed_size) && (!zipeof)) {
  906. X        if (Slen[lchar] == 0)
  907. X                        READBIT(8,nchar,(int))      /* ; */
  908. X                else
  909. X        {
  910. X                        READBIT(1,nchar,(int));
  911. X                        if (nchar != 0)
  912. X                                READBIT(8,nchar,(int))      /* ; */
  913. X                        else
  914. X            {
  915. X                                int follower;
  916. X                                int bitsneeded = B_table[Slen[lchar]];
  917. X                                READBIT(bitsneeded,follower,(int));
  918. X                                nchar = followers[lchar][follower];
  919. X            }
  920. X        }
  921. X
  922. X        /* expand the resulting byte */
  923. X        switch (ExState) {
  924. X
  925. X        case 0:
  926. X                        if (nchar != DLE)
  927. X                                OUTB((byte) nchar) /*;*/
  928. X            else
  929. X                ExState = 1;
  930. X            break;
  931. X
  932. X        case 1:
  933. X                        if (nchar != 0) {
  934. X                                V = nchar;
  935. X                Len = V & L_table[factor];
  936. X                if (Len == L_table[factor])
  937. X                    ExState = 2;
  938. X                else
  939. X                    ExState = 3;
  940. X            }
  941. X            else {
  942. X                                OUTB(DLE);
  943. X                ExState = 0;
  944. X            }
  945. X            break;
  946. X
  947. X                case 2: {
  948. X                                Len += nchar;
  949. X                ExState = 3;
  950. X            }
  951. X            break;
  952. X
  953. X                case 3: {
  954. X                register int i = Len + 3;
  955. X                int offset = (((V >> D_shift[factor]) &
  956. X                                          D_mask[factor]) << 8) + nchar + 1;
  957. X                                longint op = (outpos+outcnt) - offset;
  958. X
  959. X                /* special case- before start of file */
  960. X                while ((op < 0L) && (i > 0)) {
  961. X                    OUTB(0);
  962. X                    op++;
  963. X                    i--;
  964. X                }
  965. X
  966. X                /* normal copy of data from output buffer */
  967. X                {
  968. X                    register int ix = (int) (op % OUTBUFSIZ);
  969. X
  970. X                                        /* do a block memory copy if possible */
  971. X                                        if ( ((ix    +i) < OUTBUFSIZ) &&
  972. X                                             ((outcnt+i) < OUTBUFSIZ) ) {
  973. X                                                memcpy(outptr,&outbuf[ix],i);
  974. X                                                outptr += i;
  975. X                                                outcnt += i;
  976. X                                        }
  977. X
  978. X                                        /* otherwise copy byte by byte */
  979. X                                        else while (i--) {
  980. X                                                OUTB(outbuf[ix]);
  981. X                                                if (++ix >= OUTBUFSIZ)
  982. X                                                        ix = 0;
  983. X                                        }
  984. X                                }
  985. X
  986. X                ExState = 0;
  987. X            }
  988. X            break;
  989. X        }
  990. X
  991. X                /* store character for next iteration */
  992. X                lchar = nchar;
  993. X        }
  994. X}
  995. X
  996. X
  997. X/* ------------------------------------------------------------- */
  998. X/*
  999. X * Shrinking is a Dynamic Ziv-Lempel-Welch compression algorithm
  1000. X * with partial clearing.
  1001. X *
  1002. X */
  1003. X
  1004. Xvoid partial_clear(VOIDARG)
  1005. X{
  1006. X        register int pr;
  1007. X        register int cd;
  1008. X
  1009. X    /* mark all nodes as potentially unused */
  1010. X    for (cd = first_ent; cd < free_ent; cd++)
  1011. X        prefix_of[cd] |= 0x8000;
  1012. X
  1013. X    /* unmark those that are used by other nodes */
  1014. X    for (cd = first_ent; cd < free_ent; cd++) {
  1015. X        pr = prefix_of[cd] & 0x7fff;    /* reference to another node? */
  1016. X                if (pr >= first_ent)            /* flag node as referenced */
  1017. X            prefix_of[pr] &= 0x7fff;
  1018. X    }
  1019. X
  1020. X    /* clear the ones that are still marked */
  1021. X    for (cd = first_ent; cd < free_ent; cd++)
  1022. X        if ((prefix_of[cd] & 0x8000) != 0)
  1023. X            prefix_of[cd] = -1;
  1024. X
  1025. X    /* find first cleared node as next free_ent */
  1026. X        cd = first_ent;
  1027. X        while ((cd < maxcodemax) && (prefix_of[cd] != -1))
  1028. X                cd++;
  1029. X        free_ent = cd;
  1030. X}
  1031. X
  1032. X
  1033. X/* ------------------------------------------------------------- */
  1034. X
  1035. Xvoid unShrink(VOIDARG)
  1036. X{
  1037. X#define  GetCode(dest) READBIT(codesize,dest,(int))
  1038. X
  1039. X    register int code;
  1040. X    register int stackp;
  1041. X    int finchar;
  1042. X    int oldcode;
  1043. X    int incode;
  1044. X
  1045. X
  1046. X    /* decompress the file */
  1047. X    maxcodemax = 1 << max_bits;
  1048. X    codesize = init_bits;
  1049. X    maxcode = (1 << codesize) - 1;
  1050. X    free_ent = first_ent;
  1051. X    offset = 0;
  1052. X    sizex = 0;
  1053. X
  1054. X    for (code = maxcodemax; code > 255; code--)
  1055. X        prefix_of[code] = -1;
  1056. X
  1057. X    for (code = 255; code >= 0; code--) {
  1058. X        prefix_of[code] = 0;
  1059. X        suffix_of[code] = (byte) code;
  1060. X    }
  1061. X
  1062. X    GetCode(oldcode);
  1063. X    if (zipeof)
  1064. X        return;
  1065. X    finchar = oldcode;
  1066. X
  1067. X        OUTB((byte) finchar);
  1068. X
  1069. X        stackp = hsize;
  1070. X
  1071. X    while (!zipeof) {
  1072. X        GetCode(code);
  1073. X        if (zipeof)
  1074. X            return;
  1075. X
  1076. X        while (code == clear) {
  1077. X            GetCode(code);
  1078. X            switch (code) {
  1079. X
  1080. X            case 1:{
  1081. X                    codesize++;
  1082. X                    if (codesize == max_bits)
  1083. X                        maxcode = maxcodemax;
  1084. X                    else
  1085. X                        maxcode = (1 << codesize) - 1;
  1086. X                }
  1087. X                break;
  1088. X
  1089. X            case 2:
  1090. X                partial_clear();
  1091. X                break;
  1092. X            }
  1093. X
  1094. X            GetCode(code);
  1095. X            if (zipeof)
  1096. X                return;
  1097. X        }
  1098. X
  1099. X
  1100. X        /* special case for KwKwK string */
  1101. X        incode = code;
  1102. X        if (prefix_of[code] == -1) {
  1103. X                        stack[--stackp] = (byte) finchar;
  1104. X            code = oldcode;
  1105. X        }
  1106. X
  1107. X
  1108. X        /* generate output characters in reverse order */
  1109. X        while (code >= first_ent) {
  1110. X                        stack[--stackp] = suffix_of[code];
  1111. X            code = prefix_of[code];
  1112. X        }
  1113. X
  1114. X        finchar = suffix_of[code];
  1115. X                stack[--stackp] = (byte) finchar;
  1116. X
  1117. X
  1118. X                /* and put them out in forward order, block copy */
  1119. X                if ((hsize-stackp+outcnt) < OUTBUFSIZ) {
  1120. X                        memcpy(outptr,&stack[stackp],hsize-stackp);
  1121. X                        outptr += hsize-stackp;
  1122. X                        outcnt += hsize-stackp;
  1123. X                        stackp = hsize;
  1124. X                }
  1125. X
  1126. X                /* output byte by byte if we can't go by blocks */
  1127. X                else while (stackp < hsize)
  1128. X                        OUTB(stack[stackp++]);
  1129. X
  1130. X
  1131. X        /* generate new entry */
  1132. X        code = free_ent;
  1133. X        if (code < maxcodemax) {
  1134. X            prefix_of[code] = oldcode;
  1135. X            suffix_of[code] = (byte) finchar;
  1136. X
  1137. X            do
  1138. X                code++;
  1139. X            while ((code < maxcodemax) && (prefix_of[code] != -1));
  1140. X
  1141. X            free_ent = code;
  1142. X        }
  1143. X
  1144. X        /* remember previous code */
  1145. X        oldcode = incode;
  1146. X    }
  1147. X
  1148. X}
  1149. X
  1150. X
  1151. X/* ------------------------------------------------------------- */ 
  1152. X/*
  1153. X * Imploding
  1154. X * ---------
  1155. X *
  1156. X * The Imploding algorithm is actually a combination of two distinct
  1157. X * algorithms.  The first algorithm compresses repeated byte sequences
  1158. X * using a sliding dictionary.  The second algorithm is used to compress
  1159. X * the encoding of the sliding dictionary ouput, using multiple
  1160. X * Shannon-Fano trees.
  1161. X *
  1162. X */ 
  1163. X
  1164. X#define maxSF 256
  1165. X
  1166. X   typedef struct sf_entry { 
  1167. X                 word         Code; 
  1168. X                 byte         Value; 
  1169. X                 byte         BitLength; 
  1170. X              } sf_entry; 
  1171. X
  1172. X   typedef struct sf_tree {   /* a shannon-fano tree */ 
  1173. X      sf_entry     entry[maxSF];
  1174. X      int          entries;
  1175. X      int          MaxLength;
  1176. X   } sf_tree; 
  1177. X
  1178. X   typedef sf_tree      *sf_treep; 
  1179. X
  1180. X   sf_tree      lit_tree; 
  1181. X   sf_tree      length_tree; 
  1182. X   sf_tree      distance_tree; 
  1183. X   boolean      lit_tree_present; 
  1184. X   boolean      eightK_dictionary; 
  1185. X   int          minimum_match_length;
  1186. X   int          dict_bits;
  1187. X
  1188. X
  1189. X#ifndef    OLDC
  1190. Xvoid SortLengths(sf_tree *tree)
  1191. X#else
  1192. Xvoid SortLengths(tree)
  1193. Xsf_tree *tree;
  1194. X#endif    /* OLDC */
  1195. X  /* Sort the Bit Lengths in ascending order, while retaining the order
  1196. X    of the original lengths stored in the file */ 
  1197. X{ 
  1198. X   int          x;
  1199. X   int          gap;
  1200. X   sf_entry     t; 
  1201. X   boolean      noswaps;
  1202. X   int          a, b;
  1203. X
  1204. X   gap = tree->entries / 2; 
  1205. X
  1206. X   do { 
  1207. X      do { 
  1208. X         noswaps = 1;
  1209. X         for (x = 0; x <= (tree->entries - 1) - gap; x++) 
  1210. X         { 
  1211. X            a = tree->entry[x].BitLength; 
  1212. X            b = tree->entry[x + gap].BitLength; 
  1213. X            if ((a > b) || ((a == b) && (tree->entry[x].Value > tree->entry[x + gap].Value))) 
  1214. X            { 
  1215. X               t = tree->entry[x]; 
  1216. X               tree->entry[x] = tree->entry[x + gap]; 
  1217. X               tree->entry[x + gap] = t; 
  1218. X               noswaps = 0;
  1219. X            } 
  1220. X         } 
  1221. X      }  while (!noswaps);
  1222. X
  1223. X      gap = gap / 2; 
  1224. X   }  while (gap > 0);
  1225. X} 
  1226. X
  1227. X
  1228. X/* ----------------------------------------------------------- */ 
  1229. X
  1230. X#ifndef    OLDC
  1231. Xvoid ReadLengths(sf_tree *tree)
  1232. X#else
  1233. Xvoid ReadLengths(tree)
  1234. Xsf_tree *tree;
  1235. X#endif    /* OLDC */
  1236. X{ 
  1237. X   int          treeBytes;
  1238. X   int          i;
  1239. X   int          num, len;
  1240. X
  1241. X  /* get number of bytes in compressed tree */
  1242. X   READBIT(8,treeBytes,(int));
  1243. X   treeBytes++; 
  1244. X   i = 0; 
  1245. X
  1246. X   tree->MaxLength = 0;
  1247. X
  1248. X /* High 4 bits: Number of values at this bit length + 1. (1 - 16)
  1249. X    Low  4 bits: Bit Length needed to represent value + 1. (1 - 16) */
  1250. X   while (treeBytes > 0)
  1251. X   {
  1252. X      READBIT(4,len,(int)); len++;
  1253. X      READBIT(4,num,(int)); num++;
  1254. X
  1255. X      while (num > 0)
  1256. X      {
  1257. X         if (len > tree->MaxLength)
  1258. X            tree->MaxLength = len;
  1259. X         tree->entry[i].BitLength = (byte) len;
  1260. X         tree->entry[i].Value = (byte) i;
  1261. X         i++;
  1262. X         num--;
  1263. X      }
  1264. X
  1265. X      treeBytes--;
  1266. X   } 
  1267. X} 
  1268. X
  1269. X
  1270. X/* ----------------------------------------------------------- */ 
  1271. X
  1272. X#ifndef    OLDC
  1273. Xvoid GenerateTrees(sf_tree *tree)
  1274. X#else
  1275. Xvoid GenerateTrees(tree)
  1276. Xsf_tree *tree;
  1277. X#endif    /* OLDC */
  1278. X     /* Generate the Shannon-Fano trees */ 
  1279. X{ 
  1280. X   word         Code;
  1281. X   int          CodeIncrement;
  1282. X   int          LastBitLength;
  1283. X   int          i;
  1284. X
  1285. X
  1286. X   Code = 0;
  1287. X   CodeIncrement = 0; 
  1288. X   LastBitLength = 0; 
  1289. X
  1290. X   i = tree->entries - 1;   /* either 255 or 63 */ 
  1291. X   while (i >= 0) 
  1292. X   { 
  1293. X      Code += CodeIncrement; 
  1294. X      if (tree->entry[i].BitLength != (byte) LastBitLength) 
  1295. X      { 
  1296. X         LastBitLength = tree->entry[i].BitLength; 
  1297. X         CodeIncrement = 1 << (16 - LastBitLength); 
  1298. X      } 
  1299. X
  1300. X      tree->entry[i].Code = Code; 
  1301. X      i--; 
  1302. X   } 
  1303. X} 
  1304. X
  1305. X
  1306. X/* ----------------------------------------------------------- */ 
  1307. X
  1308. X#ifndef    OLDC
  1309. Xvoid ReverseBits(sf_tree *tree)
  1310. X#else
  1311. Xvoid ReverseBits(tree)
  1312. Xsf_tree *tree;
  1313. X#endif    /* OLDC */
  1314. X /* Reverse the order of all the bits in the above ShannonCode[]
  1315. X    vector, so that the most significant bit becomes the least
  1316. X    significant bit. For example, the value 0x1234 (hex) would become
  1317. X    0x2C48 (hex). */ 
  1318. X{ 
  1319. X   int          i;
  1320. X   word         mask;
  1321. X   word         revb;
  1322. X   word         v;
  1323. X   word         o;
  1324. X   int          b;
  1325. X
  1326. X
  1327. X   for (i = 0; i <= tree->entries - 1; i++) 
  1328. X   { 
  1329. X        /* get original code */ 
  1330. X      o = tree->entry[i].Code; 
  1331. X
  1332. X        /* reverse each bit */ 
  1333. X      mask = 0x0001;
  1334. X      revb = 0x8000;
  1335. X      v = 0;
  1336. X      for (b = 0; b <= 15; b++) 
  1337. X      { 
  1338. X           /* if bit set in mask, then substitute reversed bit */ 
  1339. X         if ((o & mask) != 0) 
  1340. X            v = v | revb; 
  1341. X
  1342. X           /* advance to next bit */ 
  1343. X         revb = (revb >> 1);
  1344. X         mask = (mask << 1);
  1345. X      } 
  1346. X
  1347. X        /* store reversed bits */ 
  1348. X      tree->entry[i].Code = v; 
  1349. X   } 
  1350. X} 
  1351. X
  1352. X
  1353. X/* ----------------------------------------------------------- */ 
  1354. X
  1355. X#ifndef    OLDC
  1356. Xvoid LoadTree(sf_tree *tree, int treesize)
  1357. X#else
  1358. Xvoid LoadTree(tree, treesize)
  1359. Xsf_tree *tree;
  1360. Xint treesize;
  1361. X#endif    /* OLDC */
  1362. X     /* allocate and load a shannon-fano tree from the compressed file */ 
  1363. X{ 
  1364. X   tree->entries = treesize; 
  1365. X   ReadLengths(tree); 
  1366. X   SortLengths(tree); 
  1367. X   GenerateTrees(tree); 
  1368. X   ReverseBits(tree); 
  1369. X} 
  1370. X
  1371. X
  1372. X/* ----------------------------------------------------------- */ 
  1373. X
  1374. X#ifndef    OLDC
  1375. Xvoid LoadTrees(void)
  1376. X#else
  1377. Xvoid LoadTrees()
  1378. X#endif    /* OLDC */
  1379. X{ 
  1380. X   /* bit 1... */
  1381. X   eightK_dictionary = (boolean) ((lrec.general_purpose_bit_flag & 0x02) != 0);
  1382. X   /* bit 2... */
  1383. X   lit_tree_present = (boolean) ((lrec.general_purpose_bit_flag & 0x04) != 0);
  1384. X
  1385. X   if (eightK_dictionary) 
  1386. X      dict_bits = 7;
  1387. X   else 
  1388. X      dict_bits = 6; 
  1389. X
  1390. X   if (lit_tree_present) 
  1391. X   { 
  1392. X      minimum_match_length = 3; 
  1393. X      LoadTree(&lit_tree,256); 
  1394. X   } 
  1395. X   else 
  1396. X      minimum_match_length = 2; 
  1397. X
  1398. X   LoadTree(&length_tree,64); 
  1399. X   LoadTree(&distance_tree,64); 
  1400. X} 
  1401. X
  1402. X
  1403. X/* ----------------------------------------------------------- */ 
  1404. X
  1405. X#ifndef    OLDC
  1406. Xvoid ReadTree(sf_tree *tree, int *dest)
  1407. X#else
  1408. Xvoid ReadTree(tree, dest)
  1409. Xsf_tree *tree;
  1410. Xint *dest;
  1411. X#endif    /* OLDC */
  1412. X     /* read next byte using a shannon-fano tree */ 
  1413. X{ 
  1414. X   int          bits = 0;
  1415. X   word         cv = 0;
  1416. X   int          cur = 0;
  1417. X   int          b;
  1418. X
  1419. X   *dest = -1;   /* in case of error */ 
  1420. X
  1421. X   for (;;)
  1422. X   { 
  1423. X      READBIT(1,b,(int));
  1424. X      cv = cv | (b << bits);
  1425. X      bits++; 
  1426. X
  1427. X      /* this is a very poor way of decoding shannon-fano.  two quicker
  1428. X         methods come to mind:
  1429. X            a) arrange the tree as a huffman-style binary tree with
  1430. X               a "leaf" indicator at each node,
  1431. X         and
  1432. X            b) take advantage of the fact that s-f codes are at most 8
  1433. X               bits long and alias unused codes for all bits following
  1434. X               the "leaf" bit.
  1435. X      */
  1436. X
  1437. X      while (tree->entry[cur].BitLength < (byte) bits) 
  1438. X      { 
  1439. X         cur++; 
  1440. X         if (cur >= tree->entries) 
  1441. X            return; /* data error */
  1442. X      } 
  1443. X
  1444. X      while (tree->entry[cur].BitLength == (byte) bits) 
  1445. X      { 
  1446. X         if (tree->entry[cur].Code == cv) 
  1447. X         { 
  1448. X            *dest = tree->entry[cur].Value; 
  1449. X            return; 
  1450. X         } 
  1451. X
  1452. X         cur++; 
  1453. X         if (cur >= tree->entries) 
  1454. X            return; /* data error */
  1455. X      } 
  1456. X   } 
  1457. X} 
  1458. X
  1459. X
  1460. X/* ----------------------------------------------------------- */ 
  1461. X
  1462. X#ifndef    OLDC
  1463. Xvoid unImplode(void)
  1464. X#else
  1465. Xvoid unImplode()
  1466. X#endif    /* OLDC */
  1467. X     /* expand imploded data */ 
  1468. X
  1469. X{ 
  1470. X   int          lout;
  1471. X   longint      op;
  1472. X   int          Length;
  1473. X   int          Distance;
  1474. X
  1475. X   LoadTrees(); 
  1476. X
  1477. X   while ((!zipeof) && ((outpos+outcnt) < lrec.uncompressed_size))
  1478. X   { 
  1479. X      READBIT(1,lout,(int));
  1480. X
  1481. X      if (lout != 0)   /* encoded data is literal data */ 
  1482. X      { 
  1483. X         if (lit_tree_present)  /* use Literal Shannon-Fano tree */
  1484. X            ReadTree(&lit_tree,&lout);
  1485. X         else 
  1486. X            READBIT(8,lout,(int));
  1487. X
  1488. X         OUTB((byte) lout);
  1489. X      } 
  1490. X      else             /* encoded data is sliding dictionary match */
  1491. X      {                
  1492. X         READBIT(dict_bits,lout,(int));
  1493. X         Distance = lout; 
  1494. X
  1495. X         ReadTree(&distance_tree,&lout); 
  1496. X         Distance |= (lout << dict_bits);
  1497. X         /* using the Distance Shannon-Fano tree, read and decode the
  1498. X            upper 6 bits of the Distance value */ 
  1499. X
  1500. X         ReadTree(&length_tree,&Length); 
  1501. X         /* using the Length Shannon-Fano tree, read and decode the
  1502. X            Length value */
  1503. X
  1504. X         Length += minimum_match_length; 
  1505. X         if (Length == (63 + minimum_match_length)) 
  1506. X         { 
  1507. X            READBIT(8,lout,(int));
  1508. X            Length += lout; 
  1509. X         } 
  1510. X
  1511. X        /* move backwards Distance+1 bytes in the output stream, and copy
  1512. X          Length characters from this position to the output stream.
  1513. X          (if this position is before the start of the output stream,
  1514. X          then assume that all the data before the start of the output
  1515. X          stream is filled with zeros) */ 
  1516. X
  1517. X         op = (outpos+outcnt) - Distance - 1L;
  1518. X
  1519. X          /* special case- before start of file */
  1520. X          while ((op < 0L) && (Length > 0)) {
  1521. X                  OUTB(0);
  1522. X                  op++;
  1523. X                  Length--;
  1524. X          }
  1525. X
  1526. X          /* normal copy of data from output buffer */
  1527. X          {
  1528. X                  register int ix = (int) (op % OUTBUFSIZ);
  1529. X
  1530. X                  /* do a block memory copy if possible */
  1531. X                  if ( ((ix    +Length) < OUTBUFSIZ) &&
  1532. X                       ((outcnt+Length) < OUTBUFSIZ) ) {
  1533. X                          memcpy(outptr,&outbuf[ix],Length);
  1534. X                          outptr += Length;
  1535. X                          outcnt += Length;
  1536. X                  }
  1537. X
  1538. X                  /* otherwise copy byte by byte */
  1539. X                  else while (Length--) {
  1540. X                          OUTB(outbuf[ix]);
  1541. X                          if (++ix >= OUTBUFSIZ)
  1542. X                                  ix = 0;
  1543. X                  }
  1544. X         }
  1545. X      } 
  1546. X   } 
  1547. X} 
  1548. X
  1549. X
  1550. X
  1551. X/* ---------------------------------------------------------- */
  1552. X
  1553. Xvoid extract_member(VOIDARG)
  1554. X{
  1555. X        unsigned b;
  1556. X
  1557. X    bits_left = 0;
  1558. X    bitbuf = 0;
  1559. X    incnt = 0;
  1560. X    outpos = 0L;
  1561. X    outcnt = 0;
  1562. X    outptr = outbuf;
  1563. X    zipeof = 0;
  1564. X    crc32val = 0xFFFFFFFFL;
  1565. X
  1566. X
  1567. X    /* create the output file with READ and WRITE permissions */
  1568. X    if (create_output_file())
  1569. X        exit(1);
  1570. X
  1571. X        switch (lrec.compression_method) {
  1572. X
  1573. X    case 0:        /* stored */
  1574. X        {
  1575. X            printf(" Extracting: %-12s ", filename);
  1576. X            while (ReadByte(&b))
  1577. X                OUTB((byte) b);
  1578. X        }
  1579. X        break;
  1580. X
  1581. X        case 1: {
  1582. X            printf("UnShrinking: %-12s ", filename);
  1583. X            unShrink();
  1584. X        }
  1585. X        break;
  1586. X
  1587. X    case 2:
  1588. X    case 3:
  1589. X    case 4:
  1590. X        case 5: {
  1591. X            printf("  Expanding: %-12s ", filename);
  1592. X            unReduce();
  1593. X        }
  1594. X        break;
  1595. X
  1596. X        case 6: {
  1597. X                        printf("  Exploding: %-12s ", filename);
  1598. X                        unImplode();
  1599. X        }
  1600. X        break;
  1601. X
  1602. X        default:
  1603. X        printf("Unknown compression method.");
  1604. X    }
  1605. X
  1606. X
  1607. X    /* write the last partial buffer, if any */
  1608. X    if (outcnt > 0) {
  1609. X        UpdateCRC(outbuf, outcnt);
  1610. X        write(outfd, outbuf, outcnt);
  1611. X    }
  1612. X
  1613. X    /* set output file date and time */
  1614. X    set_file_time();
  1615. X
  1616. X    close(outfd);
  1617. X
  1618. X    crc32val = -1 - crc32val;
  1619. X        if (crc32val != lrec.crc32)
  1620. X                printf(" Bad CRC %08lx  (should be %08lx)", lrec.crc32, crc32val);
  1621. X
  1622. X    printf("\n");
  1623. X}
  1624. X
  1625. X
  1626. X/* ---------------------------------------------------------- */
  1627. X
  1628. X#ifndef    OLDC
  1629. Xvoid get_string(int len, char *s)
  1630. X#else
  1631. Xvoid get_string(len, s)
  1632. Xint len;
  1633. Xchar *s;
  1634. X#endif    /* OLDC */
  1635. X /* read a byte; return 8 if byte available, 0 if not */
  1636. X{
  1637. X    read(zipfd, s, len);
  1638. X    s[len] = 0;
  1639. X}
  1640. X
  1641. X
  1642. X/* ---------------------------------------------------------- */
  1643. X
  1644. Xvoid process_local_file_header(VOIDARG)
  1645. X{
  1646. X    if ((long) &lrec.crc32 ==
  1647. X            (long) &lrec.last_mod_file_date
  1648. X            + sizeof(lrec.last_mod_file_date))
  1649. X        read(zipfd, (char *) &lrec, sizeof(lrec));
  1650. X    else {
  1651. X        read(zipfd, (char *) &lrec, (unsigned)
  1652. X            ((long) &lrec.last_mod_file_date
  1653. X            + sizeof(lrec.last_mod_file_date)
  1654. X            - (long) &lrec));
  1655. X        read(zipfd, (char *) &lrec.crc32, (unsigned)
  1656. X            ((long) &lrec.extra_field_length
  1657. X            + sizeof(lrec.extra_field_length)
  1658. X            - (long) &lrec.crc32));
  1659. X    }
  1660. X
  1661. X#ifdef HIGH_LOW
  1662. X    swap_bytes(&lrec.version_needed_to_extract);
  1663. X    swap_bytes(&lrec.general_purpose_bit_flag);
  1664. X    swap_bytes(&lrec.compression_method);
  1665. X    swap_bytes(&lrec.last_mod_file_time);
  1666. X    swap_bytes(&lrec.last_mod_file_date);
  1667. X    swap_lbytes(&lrec.crc32);
  1668. X    swap_lbytes(&lrec.compressed_size);
  1669. X    swap_lbytes(&lrec.uncompressed_size);
  1670. X    swap_bytes(&lrec.filename_length);
  1671. X    swap_bytes(&lrec.extra_field_length);
  1672. X#endif    /* HIGH_LOW */
  1673. X
  1674. X    get_string(lrec.filename_length, filename);
  1675. X    get_string(lrec.extra_field_length, extra);
  1676. X#ifdef    unix
  1677. X    {
  1678. X        char *cp;
  1679. X        for (cp = filename; *cp; ++cp)
  1680. X            if (isupper(*cp)) *cp = tolower(*cp);
  1681. X    }
  1682. X#endif    /* unix */
  1683. X    extract_member();
  1684. X}
  1685. X
  1686. X
  1687. X/* ---------------------------------------------------------- */
  1688. X
  1689. Xvoid process_central_file_header(VOIDARG)
  1690. X{
  1691. X    central_directory_file_header rec;
  1692. X    char filename[STRSIZ];
  1693. X    char extra[STRSIZ];
  1694. X    char comment[STRSIZ];
  1695. X
  1696. X    if ((long) &rec.external_file_attributes ==
  1697. X            (long) &rec.internal_file_attributes
  1698. X            + sizeof(rec.internal_file_attributes))
  1699. X        read(zipfd, (char *) &rec, sizeof(rec));
  1700. X    else {
  1701. X        read(zipfd, (char *) &rec, (unsigned)
  1702. X            ((long) &rec.internal_file_attributes
  1703. X            + sizeof(rec.internal_file_attributes)
  1704. X            - (long) &rec));
  1705. X        read(zipfd, (char *) &rec.external_file_attributes, (unsigned)
  1706. X            ((long) &rec.relative_offset_local_header
  1707. X            + sizeof(rec.relative_offset_local_header)
  1708. X            - (long) &rec.external_file_attributes));
  1709. X    }
  1710. X
  1711. X#ifdef HIGH_LOW
  1712. X    swap_bytes(&rec.version_made_by);
  1713. X    swap_bytes(&rec.version_needed_to_extract);
  1714. X    swap_bytes(&rec.general_purpose_bit_flag);
  1715. X    swap_bytes(&rec.compression_method);
  1716. X    swap_bytes(&rec.last_mod_file_time);
  1717. X    swap_bytes(&rec.last_mod_file_date);
  1718. X    swap_lbytes(&rec.crc32);
  1719. X    swap_lbytes(&rec.compressed_size);
  1720. X    swap_lbytes(&rec.uncompressed_size);
  1721. X    swap_bytes(&rec.filename_length);
  1722. X    swap_bytes(&rec.extra_field_length);
  1723. X    swap_bytes(&rec.file_comment_length);
  1724. X    swap_bytes(&rec.disk_number_start);
  1725. X    swap_bytes(&rec.internal_file_attributes);
  1726. X    swap_lbytes(&rec.external_file_attributes);
  1727. X    swap_lbytes(&rec.relative_offset_local_header);
  1728. X#endif    /* HIGH_LOW */
  1729. X
  1730. X        get_string(rec.filename_length, filename);
  1731. X    get_string(rec.extra_field_length, extra);
  1732. X    get_string(rec.file_comment_length, comment);
  1733. X#ifdef    unix
  1734. X    {
  1735. X        char *cp;
  1736. X        for (cp = filename; *cp; ++cp)
  1737. X            if (isupper(*cp)) *cp = tolower(*cp);
  1738. X    }
  1739. X#endif    /* unix */
  1740. X}
  1741. X
  1742. X
  1743. X/* ---------------------------------------------------------- */
  1744. X
  1745. Xvoid process_end_central_dir(VOIDARG)
  1746. X{
  1747. X    end_central_dir_record rec;
  1748. X    char comment[STRSIZ];
  1749. X
  1750. X    read(zipfd, (char *) &rec, sizeof(rec));
  1751. X
  1752. X#ifdef HIGH_LOW
  1753. X    swap_bytes(&rec.number_this_disk);
  1754. X#ifndef    TURBOC
  1755. X    swap_bytes(&rec.num_disk_with_start_cent_dir);
  1756. X    swap_bytes(&rec.tot_ents_cent_dir_on_this_disk);
  1757. X#else
  1758. X    swap_bytes(&rec.number_disk_with_start_central_directory);
  1759. X    swap_bytes(&rec.total_entries_central_dir_on_this_disk);
  1760. X#endif    /* TURBOC */
  1761. X    swap_bytes(&rec.total_entries_central_dir);
  1762. X    swap_lbytes(&rec.size_central_directory);
  1763. X    swap_lbytes(&rec.offset_start_central_directory);
  1764. X    swap_bytes(&rec.zipfile_comment_length);
  1765. X#endif    /* HIGH_LOW */
  1766. X
  1767. X    get_string(rec.zipfile_comment_length, comment);
  1768. X}
  1769. X
  1770. X
  1771. X/* ---------------------------------------------------------- */
  1772. X
  1773. Xvoid process_headers(VOIDARG)
  1774. X{
  1775. X    longint sig;
  1776. X
  1777. X    while (1) {
  1778. X        if (read(zipfd, (char *) &sig, sizeof(sig)) != sizeof(sig))
  1779. X            return;
  1780. X
  1781. X#ifdef HIGH_LOW
  1782. X        swap_lbytes(&sig);
  1783. X#endif    /* HIGH_LOW */
  1784. X
  1785. X                if (sig == LOCAL_FILE_HEADER_SIGNATURE)
  1786. X            process_local_file_header();
  1787. X                else if (sig == CENTRAL_FILE_HEADER_SIGNATURE)
  1788. X            process_central_file_header();
  1789. X                else if (sig == END_CENTRAL_DIR_SIGNATURE) {
  1790. X            process_end_central_dir();
  1791. X            return;
  1792. X        }
  1793. X                else {
  1794. X            printf("Invalid Zipfile Header (0x%.8lx)\n", sig);
  1795. X            return;
  1796. X        }
  1797. X    }
  1798. X
  1799. X}
  1800. X
  1801. X
  1802. X/* ---------------------------------------------------------- */
  1803. X
  1804. Xvoid extract_zipfile(VOIDARG)
  1805. X{
  1806. X    /*
  1807. X     * open the zipfile for reading and in BINARY mode to prevent cr/lf
  1808. X     * translation, which would corrupt the bitstreams 
  1809. X     */
  1810. X
  1811. X    if (open_input_file())
  1812. X        exit(1);
  1813. X
  1814. X#ifdef HIGH_LOW
  1815. X    {
  1816. X        word w_sig;
  1817. X        longint li_sig;
  1818. X        char *bp, *bp0 = (char *)&li_sig, *bp3 = ((char *)&li_sig)+3;
  1819. X
  1820. X        if (read(zipfd, (char *) &w_sig, 2) == 2)
  1821. X            if (w_sig == (LOCAL_FILE_HEADER_SIGNATURE & 0xffff)) {
  1822. X                w0 = 0;
  1823. X                w1 = 1;
  1824. X            } else {
  1825. X                w0 = 1;
  1826. X                w1 = 0;
  1827. X            }
  1828. X        lseek(zipfd, 0L, SEEK_SET);
  1829. X        if (read(zipfd, (char *) &li_sig, 4) == 4)
  1830. X            if (li_sig == LOCAL_FILE_HEADER_SIGNATURE) {
  1831. X                li0 = 0;
  1832. X                li1 = 1;
  1833. X                li2 = 2;
  1834. X                li3 = 3;
  1835. X            } else {
  1836. X                li0 = li1 = li2 = li3 = 0;
  1837. X                for (bp = bp0; bp < bp3; ++bp, ++li0)
  1838. X                    if (*bp < 0x4b && !(*bp & 0x01))
  1839. X                        break;
  1840. X                for (bp = bp0; bp < bp3; ++bp, ++li1)
  1841. X                    if (*bp < 0x4b && (*bp & 0x01))
  1842. X                        break;
  1843. X                for (bp = bp0; bp < bp3; ++bp, ++li2)
  1844. X                    if (*bp == ((LOCAL_FILE_HEADER_SIGNATURE
  1845. X                            >> 8) & 0xffL))
  1846. X                        break;
  1847. X                for (bp = bp0; bp < bp3; ++bp, ++li3)
  1848. X                    if (*bp == (LOCAL_FILE_HEADER_SIGNATURE
  1849. X                            & 0xffL))
  1850. X                        break;
  1851. X            }
  1852. X        lseek(zipfd, 0L, SEEK_SET);
  1853. X    }
  1854. X#endif    /* HIGH_LOW */
  1855. X
  1856. X    process_headers();
  1857. X
  1858. X    close(zipfd);
  1859. X}
  1860. X
  1861. X
  1862. X/* ---------------------------------------------------------- */
  1863. X/*
  1864. X * main program
  1865. X *
  1866. X */
  1867. X
  1868. X#ifndef    OLDC
  1869. Xvoid main(int argc, char **argv)
  1870. X#else
  1871. Xvoid main(argc, argv)
  1872. Xint argc;
  1873. Xchar **argv;
  1874. X#endif    /* OLDC */
  1875. X /* read a byte; return 8 if byte available, 0 if not */
  1876. X{
  1877. X    if (argc != 2) {
  1878. X                printf("\n%s\nCourtesy of:  S.H.Smith  and  The Tool Shop BBS,  (602) 279-2673.\n\n",VERSION);
  1879. X        printf("You may copy and distribute this program freely, provided that:\n");
  1880. X        printf("    1)   No fee is charged for such copying and distribution, and\n");
  1881. X        printf("    2)   It is distributed ONLY in its original, unmodified state.\n\n");
  1882. X        printf("If you wish to distribute a modified version of this program, you MUST\n");
  1883. X        printf("include the source code.\n\n");
  1884. X        printf("If you modify this program, I would appreciate a copy of the  new source\n");
  1885. X        printf("code.   I am holding the copyright on the source code, so please don't\n");
  1886. X        printf("delete my name from the program files or from the documentation.\n\n");
  1887. X                printf("IN NO EVENT WILL I BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY LOST\n");
  1888. X                printf("PROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES\n");
  1889. X                printf("ARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR FOR ANY\n");
  1890. X                printf("CLAIM BY ANY OTHER PARTY.\n\n");
  1891. X                printf("Usage:  UnZip FILE[.zip]\n");
  1892. X                exit(1);
  1893. X    }
  1894. X
  1895. X    /* .ZIP default if none provided by user */
  1896. X    strcpy(zipfn, argv[1]);
  1897. X    if (strchr(zipfn, '.') == NULL)
  1898. X        strcat(zipfn, ".zip");
  1899. X
  1900. X        /* allocate i/o buffers */
  1901. X    inbuf = (byte *) (malloc(INBUFSIZ));
  1902. X    outbuf = (byte *) (malloc(OUTBUFSIZ));
  1903. X    if ((inbuf == NULL) || (outbuf == NULL)) {
  1904. X        printf("Can't allocate buffers!\n");
  1905. X        exit(1);
  1906. X    }
  1907. X
  1908. X        /* do the job... */
  1909. X        extract_zipfile();
  1910. X    exit(0);
  1911. X}
  1912. X
  1913. SHAR_EOF
  1914. fi
  1915. if test -f 'unzip.doc'
  1916. then
  1917.     echo shar: "will not over-write existing file 'unzip.doc'"
  1918. else
  1919. sed 's/^X//' << \SHAR_EOF > 'unzip.doc'
  1920. X  
  1921. X                                   UnZip
  1922. X  
  1923. X                           Version 2.0.1, 09-16-89
  1924. X  
  1925. X                           Zipfile Extract Utility
  1926. X  
  1927. X          Copyright (C) 1989 Samuel H. Smith;  ALL RIGHTS RESERVED
  1928. X  
  1929. X  
  1930. X'UnZip' is a small Zipfile extract utility.   It is written to be as
  1931. Xsmall and portable as possible -- ideal as a starting point for handling
  1932. X.ZIP files in non-IBM environments.
  1933. X
  1934. XSource code is provided in C and Turbo Pascal.  If you port this program
  1935. Xto a non-IBM system, I would appreciate a copy of the ported source and
  1936. Xexec files.
  1937. X
  1938. X
  1939. XUsage
  1940. X-----
  1941. X   unz filename[.zip]           ;pascal language version
  1942. X   unzip filename[.zip]         ;C language version
  1943. X
  1944. X
  1945. XRevision history
  1946. X----------------
  1947. X
  1948. X3-3-89
  1949. X   Initial alpha test release.
  1950. X
  1951. X3-5-89
  1952. X   First fully operational release.  Does not implement CRC verification,
  1953. X   but should correctly unzip all compression methods.
  1954. X
  1955. X3-6-89
  1956. X   Corrected end-of-file detection in both shrink and reduce expanders.
  1957. X   Resulting files should now always have the correct size.  Added ".ZIP"
  1958. X   default to unzip.c to match calling conventions of unz.pas.
  1959. X
  1960. X3-8-89
  1961. X   Moved machine and operating-system specific code to a block starting
  1962. X   around line 180.  Added code to swap bytes on host machines that
  1963. X   store the high order bytes in lower address locations than the low
  1964. X   order bytes.
  1965. X
  1966. X3-15-89
  1967. X   Added CRC checking in UNZIP.C.  Speeded operation by about 150%.
  1968. X
  1969. X   I'm spending my time on the C version now and don't plan to do any
  1970. X   further work on the pascal.  If you're using the pascal version
  1971. X   please contact me.
  1972. X
  1973. X9-9-89
  1974. X   Addition of new "un-implode" logic to handle new compression format
  1975. X   included with PKZ101.
  1976. X
  1977. X9-16-89
  1978. X   Portable version created by George M. Sipe (rebel!george).  Should
  1979. X   now more easily be ported to other systems and compilers.
  1980. X
  1981. X
  1982. X
  1983. XLICENSE
  1984. X=======
  1985. X
  1986. XYou may copy and distribute this program freely, provided that:
  1987. X    1)   No fee is charged for such copying and distribution, and
  1988. X    2)   It is distributed ONLY in its original, unmodified state.
  1989. X
  1990. XIf you wish to distribute a modified version of this program, you MUST
  1991. Xinclude the source code.
  1992. X
  1993. XIf you modify this program, I would appreciate a copy of the new source
  1994. Xcode.  I am holding the copyright on the source code, so please don't
  1995. Xdelete my name from the program files or from the documentation.
  1996. X
  1997. X
  1998. XSUPPORT
  1999. X=======
  2000. X
  2001. XI work very hard to produce a software package of the highest quality
  2002. Xand functionality.  I try to look into all reported bugs, and will
  2003. Xgenerally fix reported problems within a few days.
  2004. X
  2005. XIN NO EVENT WILL I BE LIABLE TO YOU FOR ANY DAMAGES, INCLUDING ANY LOST
  2006. XPROFITS, LOST SAVINGS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES
  2007. XARISING OUT OF YOUR USE OR INABILITY TO USE THE PROGRAM, OR FOR ANY
  2008. XCLAIM BY ANY OTHER PARTY.
  2009. X
  2010. XIf you have any questions, bugs, or suggestions, please contact me at:
  2011. X
  2012. X                  The Tool Shop BBS
  2013. X                  (602) 279-2673 (FREE LINE, USR 2400)
  2014. X                  (602) 264-3969 (HST 9600)
  2015. X                  (602) 270-0239 (HAYES 9600)
  2016. X
  2017. XThe latest version is always available for downloading.  (Except
  2018. Xpossibly this portable version.)
  2019. X
  2020. XEnjoy!     Samuel H. Smith
  2021. X           Author and Sysop of The Tool Shop.
  2022. X   
  2023. SHAR_EOF
  2024. fi
  2025. exit 0
  2026. #    End of shell archive
  2027.  
  2028. -- 
  2029. George M. Sipe,               Phone: (404) 447-4731
  2030. 537 Lakeshore Drive, Berkeley Lake, GA  30136-3035
  2031. UUCP: ...!{decvax,linus,rutgers}!gatech!rebel!george
  2032.  
  2033.  
  2034.